package asf.core
{
	import asf.events.ApplicationLoadProgressEvent;
	import asf.events.PopupEvent;
	import asf.interfaces.IPopup;
	import asf.log.LogLevel;
	import asf.sections.Popup;
	import asf.utils.Align;
	import asf.views.BasePopup;
	
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.filters.BlurFilter;
	import flash.utils.Dictionary;
	import flash.utils.getDefinitionByName;
	
	public class PopupsManager
	{
		private var pops:Array;
		private var popsDict:Object;
		
		private var data:XMLList;
		private var app:Application;
		
		private var activePops:Array;
		private var activePopsDict:Dictionary;
		
		private var blur:BlurFilter;
		
		public function PopupsManager( p_popupsNode:XMLList, p_app:Application )
		{
			data = p_popupsNode;
			blur = new BlurFilter( 6, 6 );
			
			app = p_app;
			activePops = new Array( );
			activePopsDict = new Dictionary( );
			
			parse( );
		}
		
		private function parse( ):void
		{
			var node:XML;
			var nodes:XMLList = data.popup;
			
			var pop:Popup;
			
			pops = new Array( );
			popsDict = new Object( );
			
			for each( node in nodes )
			{
				pop = new Popup( node, app );
				
				popsDict[ pop.id ] = pop;
				pops.push( pop );
			}
		}
		
		public function get items( ):Array
		{
			return pops.concat( );
		}
		
		public function openPopup( pop:* ):Popup
		{
			if( pop is String ) pop = getPopByID( pop );
			
			
			if( pop )
			{
				app.log( pop.id );
				
				if( pop.darkLayer != null )
				{
					pop.darkLayer.goDark( pop.darkAmount );
				}
				
				if( activePops.indexOf( pop ) != -1 )
				{
					if( ( pop as Popup ).view )
					{
						var higher:DisplayObject = ( pop.view.parent as Sprite ).getChildAt( pop.view.parent.numChildren - 1 );
						
						( pop.view as DisplayObject ).parent.swapChildren( pop.view, higher );
						
						activePops.splice( activePops.indexOf( pop ) );
						activePops.push( pop );
					}
					
					return pop;
				}
				
				if( ( pop as Popup ).isLoaded )
				{
					doShowPop( pop );
				}
				else
				{
					( pop as Popup ).addEventListener( ApplicationLoadProgressEvent.DEPENDENCIES_LOAD_COMPLETE, popLoadComplete );
					( pop as Popup ).load( );
				}
				
				activePops.push( pop );
				activePopsDict[ pop ] = activePops.length - 1;
			}
			
			app.container.mouseChildren = !( pop as Popup ).lock;
			
			return pop;
		}
		
		public function closePopup( pop:* ):void
		{
			if( pop is String ) pop = getPopByID( pop );
			
			var p:Popup = pop;
			
			app.log( p.id, LogLevel.INFO_3 );
			
			if( activePops.indexOf( p ) == -1 ) return;
			
			p.addEventListener( PopupEvent.HIDE_END, onPopupHide );
			
			var index:int = activePops.indexOf( p );// activePopsDict[ p ];
			
			if( index != - 1 ) activePops.splice( index, 1 );
			if( activePops.length == 0 )
			{
				app.container.mouseChildren = true;
				removeMainBlur( );
			}
			else
			{
				var last:Popup = ( activePops[ activePops.length - 1 ] as Popup );
				
				if( last.canBlur ) applyMainBlur( );
				else removeMainBlur( );
				
				app.container.mouseChildren = ! last.lock;
			}
			
			p.view.close( );
		}
		
		private function removeMainBlur( ):void
		{
			var filters:Array
			var filter:*;
			var n:uint = 0;
			
			if( app.container.filters )
			{
				filters = app.container.filters;
				
				for each( filter in filters )
				{
					if( filter is BlurFilter )
					{
						filters.splice( n, 1 );
					}
					
					n++;
				}
			}
			
			app.container.filters = filters;
		}
		
		private function onPopupHide( evt:PopupEvent ):void
		{
			var p:Popup = evt.target as Popup;
			
			removePopup( p );
		}
		
		private function removePopup( p:Popup ):void
		{
			Align.remove( p.view );
			app.popsContainer.removeChild( p.view as DisplayObject );
			
			if( p.darkLayer != null )
			{
				var pop:Popup;
				
				for each( pop in activePops )
				{
					if( pop != p && pop.darkLayer == p.darkLayer )
					{
						pop.darkLayer.goDark( pop.darkAmount );
						return;
					}
				}
				
				p.darkLayer.goDark( 0, true );
			}
			
			p.view.dispose( );
			p.unload( );
		}
		
		private function popLoadComplete( evt:ApplicationLoadProgressEvent ):void
		{
			var pop:Popup = evt.target as Popup;
			
			app.log( pop.id, LogLevel.INFO_3 );
			
			pop.removeEventListener( ApplicationLoadProgressEvent.DEPENDENCIES_LOAD_COMPLETE, popLoadComplete );
			
			doShowPop( pop );
		}
		
		private function doShowPop( pop:Popup ):void
		{
			var PopClass:Class = getDefinitionByName( pop.viewClassName ) as Class;
			var popView:BasePopup = new PopClass( ) as BasePopup;
			
			popView.popup = pop;
			pop.view = popView as IPopup;
			
			Align.add( popView, Align.CENTER + Align.MIDDLE, { margin_top: pop.margin_top, margin_bottom: pop.margin_bottom, margin_left: pop.margin_left, margin_right: pop.margin_right } );
			
			app.popsContainer.addChild( popView as DisplayObject );
			
			( popView as IPopup ).open( );
			
			if( pop.canBlur )
			{
				applyMainBlur( );
			}
		}
		
		private function applyMainBlur( ):void
		{
			var filters:Array = app.container.filters;
			var filter:*;
			
			if( filters )
			{
				for each( filter in filters )
				{
					if( filter is BlurFilter ) return;
				}
				
				filters.push( blur );
			}
			else
			{
				filters = [ blur ];
			}
			
			app.container.filters = filters;
		}
		
		public function getPopByID( id:String ):Popup
		{
			return popsDict[ id ];
		}
		
		public function getBaseLayerID( ):String
		{
			return app.getParsedValueOf( data.@layer || data.layer );
		}
	}
}